using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Microsoft.Practices.Unity.Interception
{
    [TestClass]
    public class InterceptVirtualGenericsInterceptionExtensionTest
    {
        [TestMethod]
        public void GenericMethodOnGenericClass()
        {
            Recorder.Records.Clear();
            IUnityContainer container = new UnityContainer();
            container.AddNewExtension<InterceptionExtension>();

            GenericFoo<int> obj = container.Resolve<GenericFoo<int>>();
            obj.Baz(21, 42);
            obj.Baz(96, "world");

            Assert.AreEqual(6, Recorder.Records.Count);
            Assert.AreEqual("Before Method", Recorder.Records[0]);
            Assert.AreEqual("Passed: 21, 42", Recorder.Records[1]);
            Assert.AreEqual("After Method", Recorder.Records[2]);
            Assert.AreEqual("Before Method", Recorder.Records[3]);
            Assert.AreEqual("Passed: 96, world", Recorder.Records[4]);
            Assert.AreEqual("After Method", Recorder.Records[5]);
        }

        [TestMethod]
        public void GenericMethodOnNonGenericClass()
        {
            Recorder.Records.Clear();
            IUnityContainer container = new UnityContainer();
            container.AddNewExtension<InterceptionExtension>();

            Foo obj = container.Resolve<Foo>();
            obj.Bar(42);
            obj.Bar("world");

            Assert.AreEqual(6, Recorder.Records.Count);
            Assert.AreEqual("Before Method", Recorder.Records[0]);
            Assert.AreEqual("Passed: 42", Recorder.Records[1]);
            Assert.AreEqual("After Method", Recorder.Records[2]);
            Assert.AreEqual("Before Method", Recorder.Records[3]);
            Assert.AreEqual("Passed: world", Recorder.Records[4]);
            Assert.AreEqual("After Method", Recorder.Records[5]);
        }

        [TestMethod]
        public void NonGenericMethodOnGenericClass()
        {
            Recorder.Records.Clear();
            IUnityContainer container = new UnityContainer();
            container.AddNewExtension<InterceptionExtension>();

            GenericFoo<int> obj = container.Resolve<GenericFoo<int>>();
            obj.Bar(42);

            Assert.AreEqual(3, Recorder.Records.Count);
            Assert.AreEqual("Before Method", Recorder.Records[0]);
            Assert.AreEqual("Passed: 42", Recorder.Records[1]);
            Assert.AreEqual("After Method", Recorder.Records[2]);
        }

        public class ATest : ITest
        {
            public string strtest = "Hello";
        }

        public class Foo
        {
            [VirtualIntercept(typeof(RecordingHandler))]
            public virtual void Bar<T>(T value)
            {
                Recorder.Records.Add("Passed: " + value);
            }
        }

        public class GenericFoo<T>
        {
            [VirtualIntercept(typeof(RecordingHandler))]
            public virtual void Bar(T value)
            {
                Recorder.Records.Add("Passed: " + value);
            }

            [VirtualIntercept(typeof(RecordingHandler))]
            public virtual void Baz<T1>(T value,
                                        T1 value2)
            {
                Recorder.Records.Add("Passed: " + value + ", " + value2);
            }
        }

        public interface ITest { }
    }
}